using GroupSix.Application.Dtos;
using GroupSix.Domain.Entity.App;
using GroupSix.Domain.Repositories;
using GroupSix.Domain.common;

namespace GroupSix.Application.Services;

/// <summary>
/// 角色服务
/// </summary>
public class RoleService
{
    private readonly IRoleRepository _roleRepository;
    private readonly IRepository<GsMenu> _menuRepository;

    public RoleService(IRoleRepository roleRepository, IRepository<GsMenu> menuRepository)
    {
        _roleRepository = roleRepository;
        _menuRepository = menuRepository;
    }

    /// <summary>
    /// 创建角色
    /// </summary>
    /// <param name="request">创建请求</param>
    /// <returns>角色响应</returns>
    public async Task<RoleResponseDto> CreateAsync(CreateRoleRequestDto request)
    {
        // 验证角色名称唯一性
        if (await _roleRepository.IsNameExistsAsync(request.Name))
        {
            throw new InvalidOperationException("角色名称已存在");
        }

        // 创建角色
        var role = new GsRole(request.Name, request.Description, request.Status);
        await _roleRepository.CreateAsync(role);

        // 分配菜单权限
        if (request.MenuIds.Any())
        {
            await AssignMenusToRoleAsync(role.Id, request.MenuIds);
        }

        // 返回角色信息
        return await GetRoleResponseAsync(role);
    }

    /// <summary>
    /// 更新角色
    /// </summary>
    /// <param name="request">更新请求</param>
    /// <returns>角色响应</returns>
    public async Task<RoleResponseDto> UpdateAsync(UpdateRoleRequestDto request)
    {
        // 获取角色
        var role = await _roleRepository.GetByIdAsync(request.Id);
        if (role == null)
        {
            throw new InvalidOperationException("角色不存在");
        }

        // 检查是否为超级管理员角色
        if (role.Name.Equals("超级管理员", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("超级管理员角色不能修改");
        }

        // 验证角色名称唯一性（排除当前角色）
        if (await _roleRepository.IsNameExistsAsync(request.Name, request.Id))
        {
            throw new InvalidOperationException("角色名称已存在");
        }

        // 更新角色基本信息
        role.UpdateInfo(request.Name, request.Description, request.Status);
        await _roleRepository.UpdateAsync(role);

        // 更新菜单权限
        await UpdateRoleMenusAsync(role.Id, request.MenuIds);

        // 返回角色信息
        return await GetRoleResponseAsync(role);
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>删除结果</returns>
    public async Task<bool> DeleteAsync(Guid id)
    {
        try
        {
            // 获取角色
            var role = await _roleRepository.GetByIdAsync(id);
            if (role == null)
            {
                throw new InvalidOperationException("角色不存在");
            }

            // 检查是否为超级管理员角色
            if (role.Name.Equals("超级管理员", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("超级管理员角色不能删除");
            }

            // 检查角色是否被用户使用
            if (await _roleRepository.IsUsedByUsersAsync(id))
            {
                throw new InvalidOperationException("该角色正在被用户使用，无法删除");
            }

            // 删除角色菜单关联
            await _roleRepository.DeleteRoleMenusAsync(id);

            // 删除角色（软删除）
            await _roleRepository.DeleteAsync(id);

            return true;
        }
        catch (Exception ex)
        {
            // 记录错误日志
            Console.WriteLine($"删除角色失败: {ex.Message}");
            throw;
        }
    }

    /// <summary>
    /// 获取角色列表
    /// </summary>
    /// <param name="request">查询请求</param>
    /// <returns>角色列表响应</returns>
    public async Task<RoleListResponseDto> GetListAsync(GetRolesRequestDto request)
    {
        // 构建查询条件
        var pageRequest = new PageRequest
        {
            PageIndex = request.PageIndex,
            PageSize = request.PageSize
        };

        // 查询角色列表
        var pageResult = await _roleRepository.GetPagedAsync(pageRequest, request.Name);

        // 转换为响应DTO
        var roles = new List<RoleResponseDto>();
        foreach (var role in pageResult.Items)
        {
            var roleResponse = await GetRoleResponseAsync(role);
            roles.Add(roleResponse);
        }

        return new RoleListResponseDto
        {
            Roles = roles,
            TotalCount = pageResult.TotalCount,
            PageIndex = pageResult.PageIndex,
            PageSize = pageResult.PageSize,
            TotalPages = pageResult.TotalPages
        };
    }

    /// <summary>
    /// 获取角色详情
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>角色响应</returns>
    public async Task<RoleResponseDto> GetByIdAsync(Guid id)
    {
        var role = await _roleRepository.GetWithMenusAsync(id);
        if (role == null)
        {
            throw new InvalidOperationException("角色不存在");
        }

        return await GetRoleResponseAsync(role);
    }

    /// <summary>
    /// 为角色分配菜单权限
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <param name="menuIds">菜单ID列表</param>
    /// <returns>分配结果</returns>
    public async Task<bool> AssignMenusAsync(Guid roleId, List<Guid> menuIds)
    {
        // 检查角色是否存在
        var role = await _roleRepository.GetByIdAsync(roleId);
        if (role == null)
        {
            throw new InvalidOperationException("角色不存在");
        }

        // 检查菜单是否存在
        foreach (var menuId in menuIds)
        {
            var menu = await _menuRepository.GetByIdAsync(menuId);
            if (menu == null)
            {
                throw new InvalidOperationException($"菜单ID {menuId} 不存在");
            }
        }

        // 更新角色菜单关联
        await UpdateRoleMenusAsync(roleId, menuIds);

        return true;
    }

    /// <summary>
    /// 获取角色响应DTO
    /// </summary>
    /// <param name="role">角色实体</param>
    /// <returns>角色响应DTO</returns>
    private async Task<RoleResponseDto> GetRoleResponseAsync(GsRole role)
    {
        var userCount = await _roleRepository.GetUserCountAsync(role.Id);
        var menus = role.GsRoleMenus.Select(rm => new MenuDto
        {
            Id = rm.Menu?.Id ?? Guid.Empty,
            Name = rm.Menu?.Menuname ?? string.Empty,
            Path = rm.Menu?.MenuPath,
            Icon = rm.Menu?.MenuIcon,
            Order = rm.Menu?.Order ?? 0,
            PermissionKey = rm.Menu?.PermissionKey
        }).ToList();

        return new RoleResponseDto
        {
            Id = role.Id,
            Name = role.Name,
            Description = role.Description,
            Status = role.Status,
            CreatedAt = role.CreatedAt,
            UpdatedAt = role.UpdatedAt,
            Menus = menus,
            UserCount = userCount
        };
    }

    /// <summary>
    /// 为角色分配菜单
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <param name="menuIds">菜单ID列表</param>
    private async Task AssignMenusToRoleAsync(Guid roleId, List<Guid> menuIds)
    {
        var roleMenus = menuIds.Select(menuId => new GsRoleMenu(roleId, menuId)).ToList();
        await _roleRepository.AddRoleMenusAsync(roleMenus);
    }

    /// <summary>
    /// 更新角色菜单关联
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <param name="menuIds">菜单ID列表</param>
    private async Task UpdateRoleMenusAsync(Guid roleId, List<Guid> menuIds)
    {
        // 删除现有关联
        await _roleRepository.DeleteRoleMenusAsync(roleId);

        // 添加新关联
        if (menuIds.Any())
        {
            await AssignMenusToRoleAsync(roleId, menuIds);
        }
    }
} 